package com.hkts.beltweigher.master.service.serviceimpl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hkts.beltweigher.master.entity.HktsFieldControl;
import com.hkts.beltweigher.master.entity.YbClassesAccumulate;
import com.hkts.beltweigher.master.entity.YbHourAccumulate;
import com.hkts.beltweigher.master.entity.YbRunAccumulate;
import com.hkts.beltweigher.master.mapper.YbRunAccumulateMapper;
import com.hkts.beltweigher.master.service.IYbRunAccumulateService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hkts.beltweigher.master.vo.DateStatisticsVo;
import com.hkts.beltweigher.master.vo.ReportStatisticsResultVo;
import com.hkts.beltweigher.master.vo.RunDataStaticResultVo;
import com.hkts.beltweigher.master.vo.RunDataStaticVo;
import com.hkts.beltweigher.utils.DateUtil;
import com.hkts.beltweigher.utils.Result;
import com.hkts.beltweigher.utils.ResultUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hml
 * @since 2024-04-10
 */
@Service
@Transactional
public class YbRunAccumulateServiceImpl extends ServiceImpl<YbRunAccumulateMapper, YbRunAccumulate> implements IYbRunAccumulateService {


    @Autowired
    private YbRunAccumulateMapper ybRunAccumulateMapper;

    @Override
    public IPage<YbRunAccumulate> selectPage(Page<YbRunAccumulate> page, YbRunAccumulate ybRunAccumulate) {
        QueryWrapper<YbRunAccumulate> query = Wrappers.query();
        query.lambda().ge(ybRunAccumulate.getStartTime() != null,YbRunAccumulate::getStartTime,ybRunAccumulate.getStartTime())
                .le(ybRunAccumulate.getStartTime() != null,YbRunAccumulate::getStartTime,ybRunAccumulate.getEndTime())
                .orderByDesc(YbRunAccumulate::getStartTime);
        return ybRunAccumulateMapper.selectPage(page, query);
    }


    @Override
    public Result<Object> selectList(String startTime, String endTime) throws ParseException {
        SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
        Date parse = format.parse(endTime);
        Calendar calendar   =   new GregorianCalendar();
        calendar.setTime(parse);
        calendar.add(Calendar.DATE,1);
        QueryWrapper<YbRunAccumulate> query = Wrappers.query();
        query.lambda().ge(StringUtils.isNotBlank(startTime),YbRunAccumulate::getStartTime,startTime)
                .le(StringUtils.isNotBlank(endTime),YbRunAccumulate::getEndTime,calendar.getTime())
                .orderByDesc(YbRunAccumulate::getStartTime);

        List<YbRunAccumulate> ybRunAccumulates = ybRunAccumulateMapper.selectList(query);
        List<String> collect = ybRunAccumulates.stream().map(YbRunAccumulate::getInstrumentName).distinct().collect(Collectors.toList());
        List<RunDataStaticResultVo> result=new ArrayList<>();
        for (int i = 0; i < collect.size(); i++) {
            String instrumentName = collect.get(i);
            List<YbRunAccumulate> instrumentNameList = ybRunAccumulates.stream().filter(ybRunAccumulate -> ybRunAccumulate.getInstrumentName().equals(instrumentName)).collect(Collectors.toList());
            List<LocalDateTime> dateTimeList = instrumentNameList.stream().map(YbRunAccumulate::getStartTime).distinct().collect(Collectors.toList());
            RunDataStaticResultVo vo=new RunDataStaticResultVo();
            vo.setInstrumentName(instrumentName);
            List<RunDataStaticVo> dateStatisticsList=new ArrayList<>();
            for (int i1 = 0; i1 < dateTimeList.size(); i1++) {
                LocalDateTime localDateTime = dateTimeList.get(i1);
                List<YbRunAccumulate> data = ybRunAccumulates.stream().filter(ybRunAccumulate ->
                        ybRunAccumulate.getStartTime() == localDateTime&&ybRunAccumulate.getInstrumentName().equals(instrumentName)).collect(Collectors.toList());
                RunDataStaticVo runDataStaticVo = new RunDataStaticVo();
                runDataStaticVo.setStartTime(localDateTime);
                runDataStaticVo.setStartValue(data.get(0).getStartValue());
                runDataStaticVo.setEndValue(data.get(0).getEndValue());
                runDataStaticVo.setTotalValue(data.get(0).getTotal());
                dateStatisticsList.add(runDataStaticVo);
            }
            vo.setList(dateStatisticsList);
            result.add(vo);
        }
        List<RunDataStaticResultVo> collect1 = result.stream()
                .sorted(Comparator.comparing(RunDataStaticResultVo::getInstrumentName))
                .collect(Collectors.toList());
        return ResultUtil.data(collect1);
    }

    @Override
    public YbRunAccumulate selectYbRunAccumulate(String instrumentName) {
        QueryWrapper<YbRunAccumulate> query = Wrappers.query();
        query.lambda().eq(StringUtils.isNotBlank(instrumentName),YbRunAccumulate::getInstrumentName,instrumentName)
                .last("LIMIT 1").orderByDesc(YbRunAccumulate::getId);
        return ybRunAccumulateMapper.selectOne(query);
    }
    @Override
    public List<YbRunAccumulate> selectExportList(String startTime, String endTime) throws ParseException {
        SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
        Date parse = format.parse(endTime);
        Calendar calendar   =   new GregorianCalendar();
        calendar.setTime(parse);
        calendar.add(Calendar.DATE,1);
        QueryWrapper<YbRunAccumulate> query = Wrappers.query();
        query.lambda().ge(YbRunAccumulate::getStartTime,startTime)
                .le(YbRunAccumulate::getStartTime,format.format(calendar.getTime()))
                .orderByDesc(YbRunAccumulate::getStartTime);
        return ybRunAccumulateMapper.selectList(query);
    }

    @Override
    public List<YbRunAccumulate> selectBetweenList(Integer type){
        LocalDateTime currentDateTime = LocalDateTime.now();
        LocalTime currentTime = LocalTime.now();
        LocalDateTime eightTime = LocalDateTime.of(currentDateTime.toLocalDate(), LocalTime.of(8, 0, 0));
        LocalDateTime twentyOClock = null;
        if (DateUtil.getBeforeEightTime(currentTime)){
            twentyOClock = DateUtil.getBeforeEightDate();
        }else {
            twentyOClock = LocalDateTime.of(currentDateTime.toLocalDate(), LocalTime.of(20, 0, 0));
        }

        QueryWrapper<YbRunAccumulate> query = Wrappers.query();
        if (type == 1){
            query.lambda().ge(YbRunAccumulate::getStartTime,eightTime)
                    .orderByAsc(YbRunAccumulate::getEndTime);
        }else {
            query.lambda().ge(YbRunAccumulate::getStartTime,twentyOClock)
                    .orderByAsc(YbRunAccumulate::getEndTime);
        }
        return ybRunAccumulateMapper.selectList(query);
    }

    @Override
    public Map<String, YbRunAccumulate> selectYbRunAccumulateByClass(Integer type){
        LocalDate today = LocalDate.now(); // 当前日期
        LocalDate yesterday = today.minusDays(1); // 前一天
        LocalTime time = LocalTime.of(20, 0); // 晚上8点
        LocalDateTime yesterdayEvening8 = LocalDateTime.of(yesterday, time);
        LocalDateTime currentDateTime = LocalDateTime.now();
        LocalDateTime eightTime = LocalDateTime.of(currentDateTime.toLocalDate(), LocalTime.of(8, 0, 0));
        LocalDateTime twentyOClock = LocalDateTime.of(currentDateTime.toLocalDate(), LocalTime.of(20, 0, 0));
        QueryWrapper<YbRunAccumulate> query = Wrappers.query();
        if (type == 1){
            query.select("instrument_name as instrumentName,SUM(total) as total")
                    .ge(YbRunAccumulate.START_TIME,yesterdayEvening8)
                    .le(YbRunAccumulate.END_TIME,eightTime)
                    .groupBy(YbRunAccumulate.INSTRUMENT_NAME);
        }else {
            query.select("instrument_name as instrumentName,SUM(total) as total")
                    .ge(YbRunAccumulate.START_TIME,eightTime)
                    .le(YbRunAccumulate.END_TIME,twentyOClock)
                    .groupBy(YbRunAccumulate.INSTRUMENT_NAME);
        }
        List<YbRunAccumulate> ybRunAccumulates = ybRunAccumulateMapper.selectList(query);
        Map<String, YbRunAccumulate> collect = ybRunAccumulates.stream().collect(Collectors.toMap(YbRunAccumulate::getInstrumentName, Function.identity()));
        return collect;
    }


}
